﻿using System.Windows;
using System.Windows.Input;
using SABnzbdNET.Commands;
using SABnzbdNET.Events;
using SABnzbdNET.ServiceAgents;

namespace SABnzbdNET.ViewModels
{
    public class MainViewModel : BaseViewModel
    {
        #region Fields and properties

        private readonly IEventAggregator eventAggregator;
        private DelegateCommand loadCommand; 
        private DelegateCommand refreshCommand;
        private DelegateCommand startCommand;
        private DelegateCommand pauseCommand;
        private DelegateCommand restoreCommand;
        private DelegateCommand closeApplicationCommand;
        private int tabIndex = 0;
        private string statusMessage;
        private string notifyIconTooltip;
        private bool hasBeenNotifiedOfMinimized = false;

        public ICommand LoadCommand
        {
            get { return loadCommand ?? (loadCommand = new DelegateCommand(SetWindowState)); }
        }
        public ICommand RefreshCommand
        {
            get { return refreshCommand ?? (refreshCommand = new DelegateCommand(UpdateServerStatus)); }
        }
        public ICommand StartCommand
        {
            get { return startCommand ?? (startCommand = new DelegateCommand(StartServer)); }
        }
        public ICommand PauseCommand
        {
            get { return pauseCommand ?? (pauseCommand = new DelegateCommand(PauseServer)); }
        }
        public ICommand RestoreCommand
        {
            get { return restoreCommand ?? (restoreCommand = new DelegateCommand(RestoreWindow)); }
        }
        public ICommand CloseApplicationCommand
        {
            get { return closeApplicationCommand ?? (closeApplicationCommand = new DelegateCommand(CloseApplication)); }
        }
        public int TabIndex
        {
            get { return tabIndex; }
            set { tabIndex = value; OnPropertyChanged("TabIndex"); UpdateTabContent(); }
        }
        public string StatusMessage
        {
            get { return statusMessage; }
            set { statusMessage = value; OnPropertyChanged("StatusMessage"); }
        }
        public string NotifyIconTooltip
        {
            get { return notifyIconTooltip; }
            set { notifyIconTooltip = value; OnPropertyChanged("NotifyIconTooltip"); }
        }
        public bool HasBeenNotifiedOfMinimized
        {
            get { return hasBeenNotifiedOfMinimized; }
            set { hasBeenNotifiedOfMinimized = value; OnPropertyChanged("HasBeenNotifiedOfMinimized"); }
        }

        #endregion

        public MainViewModel()
        {
            eventAggregator = EventAggregatorProvider.Instance;
            eventAggregator.Subscribe<UpdateStatusInfoMessage>(message =>
               SetStatusMessages(message.StatusMessage, message.NotifyIconMessage));
            eventAggregator.Subscribe<UpdateNotifyIconVisibilityMessage>(message => CheckTrayIcon());
            eventAggregator.Subscribe<UpdateServerMessage>(message => UpdateTabContent());
            CheckTrayIcon();
        }

        public void HandleLoadedEvent()
        {
            SetWindowState();
        }

        public void HandleStateChangedEvent()
        {
            SetWindowState();
        }

        public void HandleIsVisibleChangedEvent()
        {
            CheckTrayIcon();
        }

        private static void SetWindowState()
        {
            if (Application.Current.Windows[0].WindowState == WindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
                Application.Current.Windows[0].Hide();
        }

        private void RestoreWindow()
        {
            Application.Current.Windows[0].Show();
            UpdateServerStatus();
            Application.Current.Windows[0].WindowState = WindowState.Normal;
        }

        private void UpdateTabContent()
        {
            switch (TabIndex)
            {
                case 0:
                    eventAggregator.Publish(new UpdateServerInfoMessage());
                    break;
                case 1:
                    eventAggregator.Publish(new UpdateServerHistoryMessage());
                    break;
                case 2:
                    eventAggregator.Publish(new UpdateServerWarningsMessage());
                    break;
            }
        }

        private void CheckTrayIcon()
        {
            var visibility = Properties.Settings.Default.ShowTrayIcon ||
                (!Application.Current.Windows[0].IsVisible && Properties.Settings.Default.MinimizeToTray) ? 
                Visibility.Visible : Visibility.Collapsed;
            eventAggregator.Publish(new SetNotifyIconVisibilityMessage
            {
                Visibility = visibility
            });
        }

        private void UpdateServerStatus()
        {
            eventAggregator.Publish(new UpdateServerInfoMessage());
        }

        private void StartServer()
        {
            new ServerAgent().StartServer(UpdateServerStatus, ShowError);
        }

        private void PauseServer()
        {
            new ServerAgent().PauseServer(UpdateServerStatus, ShowError);
        }

        private void SetStatusMessages(string windowStatusMessage, string notifyIconMessage)
        {
            StatusMessage = windowStatusMessage;
            if (!string.IsNullOrEmpty(notifyIconMessage))
                NotifyIconTooltip = notifyIconMessage;
        }

        private static void ShowError(string errorMessage)
        {
            MessageBox.Show(errorMessage, "Error");
        }

        private static void CloseApplication()
        {
            Application.Current.Shutdown();
        }
    }
}
